package com.bci.internal.engine.bcibpmengine.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bci.internal.engine.bcibpmengine.instances.entity.ActHiTaskinst;
import com.bci.internal.engine.bcibpmengine.instances.entity.ActReProcdef;
import com.bci.internal.engine.bcibpmengine.instances.entity.ActRuTask;
import com.bci.internal.engine.bcibpmengine.instances.entity.ActRuVariable;
import com.bci.internal.engine.bcibpmengine.instances.mapper.ActReProcdefMapper;
import com.bci.internal.engine.bcibpmengine.instances.mapper.ActRuTaskMapper;
import com.bci.internal.engine.bcibpmengine.instances.service.ActHiTaskinstService;
import com.bci.internal.engine.bcibpmengine.instances.service.ActRuVariableService;
import com.bci.internal.engine.bcibpmengine.service.ActivitiTaskService;
import com.bci.internal.engine.bcibpmengine.utils.ConstantUtils;
import com.bci.internal.engine.bcibpmengine.vo.CompleteTaskVo;
import com.bci.internal.engine.bcibpmengine.vo.TaskVo;
import lombok.extern.slf4j.Slf4j;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jzwu
 * @since 2021/4/5 0005
 */
@Slf4j
@Service
public class ActivitiTaskServiceImpl implements ActivitiTaskService {
    @Resource
    private TaskService taskService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private ActHiTaskinstService actHiTaskinstService;
    @Resource
    private ActRuVariableService actRuVariableService;
    @Resource
    private ActReProcdefMapper actReProcdefMapper;
    @Resource
    private ActRuTaskMapper actRuTaskMapper;

    @Override
    public List<TaskVo> listTasks(String assignee, int page, int pageSize) {
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(assignee).listPage(page, pageSize);
        // TODO 下面这段循环调库要用SQL重构
        return taskList.stream().map(task -> {
            LambdaQueryWrapper<ActReProcdef> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ActReProcdef::getId, task.getProcessDefinitionId()).select(ActReProcdef::getName,
                    ActReProcdef::getDeploymentId, ActReProcdef::getResourceName);
            ActReProcdef actReProcdef = actReProcdefMapper.selectOne(queryWrapper);
            LambdaQueryWrapper<ActRuTask> actRuTaskLambdaQueryWrapper = new LambdaQueryWrapper<>();
            actRuTaskLambdaQueryWrapper.eq(ActRuTask::getExecutionId, task.getExecutionId()).select(ActRuTask::getAssignee);
            ActRuTask actRuTask = actRuTaskMapper.selectOne(actRuTaskLambdaQueryWrapper);
            TaskVo taskVo = new TaskVo();
            taskVo.setInstanceName(!StringUtils.isEmpty(actReProcdef) ? actReProcdef.getName() : "");
            taskVo.setStatus(!StringUtils.isEmpty(actRuTask) && Objects.equals(assignee, actRuTask.getAssignee()) ? "ASSIGNED" : "");
            taskVo.setDeploymentId(actReProcdef.getDeploymentId());
            taskVo.setResourceName(actReProcdef.getResourceName());
            taskVo.setNodeName(task.getName());
            BeanUtils.copyProperties(task, taskVo);
            return taskVo;
        }).sorted(Comparator.comparing(TaskVo::getCreateTime).reversed()).collect(Collectors.toList());
    }

    @Override
    public String completeTask(CompleteTaskVo completeTaskVo) {
        Assert.notNull(completeTaskVo, "流程传入完成任务参数不能为空");
        String taskId = completeTaskVo.getTaskID();
        String assignee = completeTaskVo.getAssignee();
        int pass;
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (StringUtils.isEmpty(assignee)) {
            taskService.claim(task.getId(), completeTaskVo.getAssignee());
        }
        switch (completeTaskVo.getNodeName()) {
            /* 自评节点处理方式 */
            case ConstantUtils.SELF_COMMENT:
                Map<String, Object> hmVari = new HashMap<>();
                /* 获取总监处理人 */
                List<String> assigneeDirectorList = Arrays.asList(completeTaskVo.getNextNodeAssignee().split(","));
                hmVari.put(ConstantUtils.ASSIGNEE_DIRECTOR_LIST, assigneeDirectorList);
                hmVari.put(ConstantUtils.NUMBER, assigneeDirectorList.size());
                hmVari.put(ConstantUtils.NODE_NAME, completeTaskVo.getNodeName());
                taskService.complete(taskId, hmVari, true);
                break;
            /* 总监节点处理方式 */
            case ConstantUtils.DIRTOR:
                pass = completeTaskVo.getPass();
                HashMap<String, Object> mapDirectorVra = new HashMap<>();
                mapDirectorVra.put(ConstantUtils.PASS, pass);
                updateDirtorActRuVarable(completeTaskVo, mapDirectorVra); // 更新总监网关变量值
                taskService.complete(taskId, mapDirectorVra);
                break;

            /* 总经理节点处理方式 */
            case ConstantUtils.MANAGER:
                Assert.notNull(completeTaskVo.getPass(), "总经理网关传递参数不能为空");
                pass = completeTaskVo.getPass();
                HashMap<String, Object> mapManagerVra = new HashMap<>();
                updateManagerActRuVarable(completeTaskVo, mapManagerVra); // 更新总经理网关变量值
                taskService.complete(taskId, mapManagerVra);
                break;
            default:
                break;
        }
        return assignee;
    }

    private void updateManagerActRuVarable(CompleteTaskVo completeTaskVo, HashMap<String, Object> mapManagerVra) {
        @NotBlank(message = "传入任务id不能为空") String taskId = completeTaskVo.getTaskID();
        Integer pass = completeTaskVo.getPass();
        /* 查询当前是否有网关总经理managerPass变量 */
        LambdaQueryWrapper<ActRuVariable> actRuVariableLambdaQueryWrapper = new QueryWrapper<ActRuVariable>().lambda()
                .eq(ActRuVariable::getName, ConstantUtils.MANAGER_PASS)
                .eq(ActRuVariable::getTaskId, taskId);
        /* 在变量表中获取当前处理 */
        LambdaUpdateWrapper<ActRuVariable> variableLambdaUpdateWrapper = new UpdateWrapper<ActRuVariable>().lambda()
                .eq(ActRuVariable::getName, ConstantUtils.MANAGER_PASS)
                .eq(ActRuVariable::getTaskId, taskId);
        int countManagerPass = actRuVariableService.count(actRuVariableLambdaQueryWrapper);
        /* 更新历史任务的assignee */
        actHiTaskinstService.update(new UpdateWrapper<ActHiTaskinst>().lambda().eq(ActHiTaskinst::getId, taskId)
                .set(ActHiTaskinst::getAssignee, completeTaskVo.getAssignee()));
        /* pass==0 表示通过 pass==1表示不通过 */
        switch (pass) {
            case 0:
                if (countManagerPass == 0) {
                    mapManagerVra.put(ConstantUtils.MANAGER_PASS, 1);
                } else if (countManagerPass > 0) {
                    /* 更新【总经理】managerPass 的值 */
                    actRuVariableService.update(variableLambdaUpdateWrapper.set(ActRuVariable::getText, 1)
                            .set(ActRuVariable::getLongType, 1));
                }
                break;
            case 1:
                if (countManagerPass == 0) {
                    mapManagerVra.put(ConstantUtils.MANAGER_PASS, 2);
                } else if (countManagerPass > 0) {
                    /* 更新【总经理】managerPass 的值 */
                    actRuVariableService.update(variableLambdaUpdateWrapper.set(ActRuVariable::getText, 2)
                            .set(ActRuVariable::getLongType, 1));
                }
                break;
            default:
                break;
        }
    }

    private void updateDirtorActRuVarable(CompleteTaskVo completeTaskVo, HashMap<String, Object> mapDirectorVra) {
        @NotBlank(message = "传入任务id不能为空") String taskId = completeTaskVo.getTaskID();
        Integer pass = completeTaskVo.getPass();
        String executionId = completeTaskVo.getExecutionId();
        /* 查询当前是否有网关总监result变量 */
        LambdaQueryWrapper<ActRuVariable> actRuVariableLambdaQueryWrapper = new QueryWrapper<ActRuVariable>().lambda()
                .eq(ActRuVariable::getName, ConstantUtils.RESULT)
                .eq(ActRuVariable::getTaskId, taskId);
        /* 在变量表中获取当前处理 */
        LambdaUpdateWrapper<ActRuVariable> variableLambdaUpdateWrapper = new UpdateWrapper<ActRuVariable>().lambda()
                .eq(ActRuVariable::getName, ConstantUtils.RESULT)
                .eq(ActRuVariable::getTaskId, taskId);
        int countResult = actRuVariableService.count(actRuVariableLambdaQueryWrapper);
        mapDirectorVra.put(ConstantUtils.COUNT_RESULT, countResult);
        /* pass ==1 是代表驳回 pass==0 表示同意 */
        if (Objects.equals(pass, 1) && (countResult > 0)) {
            actRuVariableService.update(variableLambdaUpdateWrapper.set(ActRuVariable::getText, "N"));
            /* 当会签中有一个驳回就要强制将会签任务结束  */
            Integer all = (Integer) runtimeService.getVariable(executionId, "nrOfInstances");
            runtimeService.setVariable(executionId, "nrOfCompletedInstances", all);

        } else if (Objects.equals(pass, 0) && (countResult > 0)) {
            mapDirectorVra.put("assigneeManger", "salaboy");
            mapDirectorVra.put("assignee", "salaboy");
            actRuVariableService.update(variableLambdaUpdateWrapper.set(ActRuVariable::getText, "Y"));
        }
    }
}